#include "sym.h"
std::ifstream* codeFile;

char Getchar()
{
    if(codeFile -> eof()) return EOF;
    char ch;
    codeFile -> get(ch);
    return ch   ;
}
bool checkToken(char c)
{
    if (c >= 'a' && c <= 'z')
        return true;
    if (c >= 'A' && c <= 'Z')
        return true;
    if (c >= '0' && c <= '9')
        return true;
    if (c == '=' || c == ',' || c == ';' ||
        c == '.' || c == '(' || c == ')' ||
        c == ':' || c == '<' || c == '>' ||
        c == '+' || c == '-' || c == '*' ||
        c == '#' || c == '/')
    {
        return true;
    }
    return false;
}
bool isLetter(char cc)
{
    if (cc >= 'a' && cc <= 'z')
        return true;
    if (cc >= 'A' && cc <= 'Z')
        return true;
    if (cc == '_')
        return true;
    return false;
}

char c;
std::string getWord()
{
    std::string s = "";
    while (!checkToken(c))
    {
        c = Getchar();
        if(c == EOF) {
            return "";
        }
    }

    if (isLetter(c))
    {
        do
        {
            s.push_back(c);
            c = Getchar();
        } while (isLetter(c) || isdigit(c));

        return s;
    }
    if (isdigit(c))
    {
        do
        {
            s.push_back(c);
            c = Getchar();
        } while (isdigit(c));
        return s;
    }

    if (c == ':')
    {
        s.push_back(c);
        c = Getchar();
        if (c == '=')
        {
            s.push_back(c);
            c = Getchar();
        }
        return s;
    }
    if (c == ',' || c == ';' || c == '.' || c == '(' ||
        c == ')' || c == '+' || c == '-' || c == '*' || c == '/' || c == '#' || c == '=')
    {
        s.push_back(c);
        c = Getchar();
        return s;
    }
    if (c == '<')
    {
        s.push_back(c);
        c = Getchar();
        if (c == '>' || c == '=')
        {
            s.push_back(c);
            c = Getchar();
        }
        return s;
    }
    if (c == '>')
    {
        s.push_back(c);
        c = Getchar();
        if (c == '=')
        {
            s.push_back(c);
            c = Getchar();
        }
        return s;
    }
}

std::vector<TOKEN*>* getSYM(std::string & in)
{
    codeFile = new std::ifstream(in);
    c = Getchar();
    std::vector<TOKEN*> *tokens = new std::vector<TOKEN*>();
    while (c != EOF)
    {
        SYM = SYMS::NILL;
        ID = "";
        NUM = 0;
        std::string word = getWord();
//        std::cout<<word<<std::endl;
        if(word.length() == 0) break;
        if (checkKey(word))
        {
            tokens ->push_back(TOKEN::newKey(SYM,word));
        }
        else if (setId(word))
        {
            tokens ->push_back(TOKEN::newID(ID,word));
        }
        else if (setNum(word))
        {
            tokens ->push_back(TOKEN::newNum(NUM,word));
        }
        else if (checkOpt(word))
        {
            tokens ->push_back(TOKEN::newOpt(SYM,word));
        }
        else {
            std::cout<<"error"<<std::endl;
            return nullptr;
        }
    }

    codeFile->close();
//    std::cout<<(*tokens).size()<<std::endl;
    return tokens;
}